home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / conv / ilbm24.lha / ilbm / readilbm.c < prev    next >
C/C++ Source or Header  |  1993-02-12  |  6KB  |  180 lines

  1. /*
  2.  *  read.c     24 bit IFF ILBM -> 24 bit Sun Raster
  3.  *  ILBM's can be compressed or uncompressed, only uncompressed
  4.  *  Sun Rasters are written. By Brett Van Sprewenburg
  5.  * 
  6.  * Credit to the ppm utilities, the developer(s) of xv, and Commodore-Amiga for
  7.  * code and ideas.
  8.  *
  9.  *  This whole thing is a bit of a hack...
  10.  *
  11.  *  Version    Date    
  12.  *   1.0    12/??/92    Initial attempts to read the 24 bit IFF ILBM format
  13.  *   1.1    2/4/93        Cleaned code, fixed bugs with read and writeilbm intergration
  14.  *   1.2    2/9/93        ANSI'fied code some more for compilation with acc
  15.  *   1.2.1    2/10/93        Checks to make sure it's a valid iff file, looks for FORM chuck id
  16.  *                Fixed a couple of minor printf bugs. 
  17.  *   1.2.2    2/11/93        Checks to make sure that there are 24 bit planes in the IFF.
  18.  *   1.2.3    2/12/93        Checked that mallocs actually got what they wanted.
  19.  *                First public release
  20.  */
  21.  
  22. #include <readilbm.h>
  23.  
  24. int ReadILBM(char *, char *);
  25.  
  26. int ReadILBM(char *ilbmfile,char *rasterfile)
  27. {
  28.     unsigned char    form[5];
  29.     unsigned char    *ubp,*bp,*runbuf;
  30.     unsigned char    *Rrow;
  31.     unsigned char    *Brow;
  32.     unsigned char    *Grow;
  33.     unsigned int    byte;
  34.     int     fd,totbytes,bytes,row,col,plane,j,subtotal;
  35.     long    bmsize,formsize;
  36.     unsigned char *body = 0;
  37.     unsigned long body_chunk_size;
  38.  
  39.     if ((fp = fopen(ilbmfile,"r")) == NULL) {
  40.       fprintf(stderr,"Open of '%s' for reading failed.\n",ilbmfile);
  41.       return -1;
  42.         }
  43.  
  44.       if ((fd = creat(rasterfile,0660)) < 0) {
  45.       fprintf(stderr,"Open of '%s' for writing failed.\n",rasterfile);
  46.       return -1;
  47.     }
  48.  
  49.     fread(form,4,1,fp);        /* FORM */
  50.     if (strcmp(form,"FORM") != NULL) {
  51.       fprintf(stderr,"'%s' is not an IFF file. Exiting.\n",ilbmfile);
  52.        fclose(fp);
  53.       close(fd);
  54.       return -2;
  55.     }
  56.     fread(&formsize,4,1,fp);    /* Size of whole form -4 */
  57.     printf("%s ",form);
  58.     fread(form,4,1,fp);        /* ILBM */
  59.     printf("%s: (%d bytes) ",form,formsize);
  60.     fread(form,4,1,fp);        /* BMHD */
  61.     fread(&bmsize,4,1,fp);        /* size of BMHD */
  62.     fread(&ilbmheader,20,1,fp);
  63.     printf("(%dx%d) (%d planes) (Compression %s)\n",ilbmheader.w,ilbmheader.h,ilbmheader.nPlanes, ilbmheader.compression == cmpByteRun1 ? "On" : "Off");
  64.  
  65.         if (ilbmheader.nPlanes != 24) {
  66.           fprintf(stderr,"Only IFF ILBM's of 24 bit planes are supported.\n");
  67.       fclose(fp);
  68.       close(fd);
  69.       return -3;
  70.         }
  71.  
  72.     fread(form,4,1,fp);        /* BODY (ANNO sometimes) */
  73.  
  74.     while ((strcmp(form,"BODY") != 0))     /* Find the damn thing */
  75.       fread(form,4,1,fp);
  76.         
  77.     fread(&body_chunk_size,4,1,fp);
  78.  
  79.     pixelrow = ALLOCROW(ilbmheader.w);
  80.     body = (unsigned char*) malloc(body_chunk_size);
  81.     runbuf = (unsigned char*) malloc(RowBytes(ilbmheader.w));
  82.     Rrow = (unsigned char*) malloc(ilbmheader.w);
  83.     Grow = (unsigned char*) malloc(ilbmheader.w);
  84.     Brow = (unsigned char*) malloc(ilbmheader.w);
  85.     if (body == NULL || pixelrow == NULL || runbuf == NULL ||
  86.         Rrow == NULL || Grow == NULL || Brow == NULL) {
  87.       fprintf(stderr,"Unable to allocate all the memory I need...\n");
  88.       fclose(fp);
  89.       close(fd);
  90.       return -4;
  91.     }
  92.  
  93.     bp = body;
  94.  
  95.         /* Define and write the Sun Raster header */
  96.     sunheader.ras_magic = RAS_MAGIC;
  97.     sunheader.ras_width = ilbmheader.w;
  98.     sunheader.ras_height = ilbmheader.h;
  99.     sunheader.ras_depth = ilbmheader.nPlanes;
  100.     sunheader.ras_length = ilbmheader.h * ilbmheader.w * 3;
  101.     sunheader.ras_type = RT_FORMAT_RGB;
  102.     sunheader.ras_maptype = RMT_NONE;
  103.     sunheader.ras_maplength = 0;
  104.     write(fd, sunheader, sizeof(sunheader));
  105.  
  106.         /* Read in the body of the ilbm */
  107.     fread(body, body_chunk_size, 1, fp); 
  108.  
  109.   for (row = 0; row < (int)ilbmheader.h; row++ ) {
  110.  
  111.     /* There are kind of colormappish */
  112.     for (col = 0; col < (int)ilbmheader.w ; col++ )
  113.       Rrow[col] = Grow[col] = Brow[col] = 0;
  114.  
  115.     for(plane = 0; plane < (int)ilbmheader.nPlanes; plane++) {
  116.       switch (ilbmheader.compression) {
  117.  
  118.         case 0:
  119.         ubp = bp;
  120.         bp += RowBytes((int)ilbmheader.w);
  121.         break;
  122.         case 1:
  123.         ubp = runbuf;
  124.             totbytes = RowBytes((int)ilbmheader.w);
  125.         do {
  126.            byte = *bp++;
  127.               if ( byte <= 127 )
  128.               for ( j = byte, totbytes -= j + 1; j >= 0; j--) {
  129.             *ubp++ = *bp++;
  130.               }
  131.             else if ( byte != 128 )
  132.               for (j = 256 - byte, totbytes -= j + 1, byte = *bp++; j >= 0; j--) {
  133.             *ubp++ = byte;
  134.               }
  135.             } while ( totbytes > 0 );
  136.         ubp = runbuf;
  137.             break;
  138.        }
  139.  
  140.        /* Break raw row buffer up into separate rgb values */
  141.        /* In order to understand this a little better, it might help */
  142.        /* to know that the pixel values in an ILBM appear to be stored */
  143.        /* bit reversed. Hence all the logical bitwise juju. */
  144.  
  145.        for ( col = 0; col < (int)ilbmheader.w; col++ )
  146.                     if ( plane < 8 )
  147.                         { /* red */
  148.                         if ( ubp[col / 8] & ( 128 >> ( col % 8 ) ) )
  149.                             Rrow[col] |= 1 << plane;
  150.                         }
  151.                     else if ( plane > 15 )
  152.                         { /* blue */
  153.                         if ( ubp[col / 8] & ( 128 >> ( col % 8 ) ) )
  154.                             Brow[col] |= 1 << (plane-16);
  155.                         }
  156.                     else
  157.                         { /* green */
  158.                         if ( ubp[col / 8] & ( 128 >> ( col % 8 ) ) )
  159.                             Grow[col] |= 1 << (plane-8);
  160.                         }
  161.     }
  162.       /* Get the rgb values out of pixel structure, pointed at by pixelrow */
  163.        for ( col = 0; col < (int)ilbmheader.w; col++ )
  164.      ASSIGN(pixelrow[col],Rrow[col],Grow[col],Brow[col]);
  165.  
  166.       /* Write out an entire row of pixel interleaved data */
  167.        write(fd, pixelrow, (int)ilbmheader.w * 3);
  168.   }
  169.  
  170.     free(Rrow);        /* Fly! Be Free!! */
  171.     free(Grow);
  172.     free(Brow);
  173.     free(runbuf);
  174.     free(pixelrow);
  175.     free(body);
  176.     fclose(fp);
  177.     close(fd);
  178.   return 0;
  179. }
  180.